package kwr;

import java.awt.Color;
import robocode.HitByBulletEvent;
import robocode.HitWallEvent;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import java.util.Random;

/**
 * The Halbird Robot.
 * @author Kit
 */
public class Halbird extends Robot {

  double[] cornerXcoord = { 0, getBattleFieldWidth() };
  double[] cornerYcoord = { 0, getBattleFieldHeight() };
  double tankLength = getHeight();
  boolean atDestination = false;

  /**
   * Move method.
   */
  public void move() {
    int xCorner = getRandom(2);
    int yCorner = getRandom(2);
    goTo(cornerXcoord[xCorner], cornerYcoord[yCorner]);
    while (atDestination) {
      if (getRandom(2) == 0) {
        orientTo(cornerXcoord[(0 - xCorner) + 1], getY());
      }
      else {
        orientTo(getX(), cornerYcoord[(0 - yCorner) + 1]);
      }
      randomWalk();
    }
  }

  /**
   * Turns the robot toward a specific point from its current heading.
   * 
   * @param xCoord describes x-coordinate to orient toward.
   * @param yCoord describes y-coordinate to orient toward.
   */
  protected void orientTo(double xCoord, double yCoord) {
    double oppLeg = getY() - yCoord;
    double adjLeg = getX() - xCoord;
    double theta = Math.toDegrees(Math.atan(Math.abs(oppLeg) / Math.abs(adjLeg)));
    if (adjLeg >= 0) {
      if (oppLeg >= 0) {
        turnRight((270 - theta) - getHeading());
      }
      else {
        turnLeft(getHeading() + (90 - theta));
      }
    }
    else {
      if (oppLeg >= 0) {
        turnRight((180 - theta) - getHeading());
      }
      else {
        turnRight((90 - theta) - getHeading());
      }
    }
  }

  /**
   * Causes robot to randomly move toward a goal destination.
   * 
   * @param xCoord describes the x-coordinate of the goal.
   * @param yCoord describes the y-coordinate of the goal.
   */
  protected void goTo(double xCoord, double yCoord) {
    orientTo(xCoord, yCoord);
    while (!atDestination) {
      randomWalk();
    }
    atDestination = true;
  }

  /**
   * Determines whether the robot should move ahead or backwards by a tank length.
   */
  protected void randomWalk() {
    int direction = getRandom(2);
    if (direction < 0) {
      ahead(getHeight() % tankLength);
    }
    else {
      back(getHeight() % tankLength);
    }
  }

  /**
   * Stops the robot from continually running into a wall, and orients it toward the origin.
   * 
   * @param event defines when the robot comes into contact with a wall.
   */
  public void onHitWall(HitWallEvent event) {
    orientTo(0, 0);
  }

  /**
   * Fires a bullet as soon as a target is scanned.
   * 
   * @param event defines when a target is scanned.
   */
  public void onScannedRobot(ScannedRobotEvent event) {
    double targetPosition = event.getBearing();
    turnRight(targetPosition);
    fire(0.1);
  }

  /**
   * Chooses a different location whenever the robot is hit.
   * 
   * @param event defines when robot is hit by a bullet.
   */
  public void onHitByBullet(HitByBulletEvent event) {
    atDestination = false;
    move();
  }

  /**
   * Provides a psuedo-random number.
   * 
   * @param maxValue determines the maximum value of the number.
   * @return an integer between [0, maxVal-1].
   */
  private int getRandom(int maxValue) {
    Random generator = new Random();
    return generator.nextInt(maxValue);
  }

  /**
   * Colors robot and loops movement command until there are no opponents left.
   */
  public void run() {
    // Set colors
    setBodyColor(Color.red);
    setGunColor(Color.black);
    setRadarColor(Color.yellow);
    setBulletColor(Color.green);
    setScanColor(Color.green);

    while (getOthers() > 0) {
      move();
    }
  }
}
